#ifndef __UID_KEY_FLASH_H
#define __UID_KEY_FLASH_H

//写入时若值不为0xff的话，写入会失败


#include "stm32f0xx.h"                  // Device header

#include <string.h>

#define fmc_unlock FLASH_Unlock
#define fmc_lock FLASH_Lock
#define fmc_halfword_program FLASH_ProgramHalfWord
#define fmc_word_program FLASH_ProgramWord
#define fmc_page_erase FLASH_ErasePage
#define FMC_READY FLASH_COMPLETE

//#define CARD_NUM_MAX 10000

#define FLASH_ADDRESS_END 0x0800FFFF //64	


//缓冲区
#define FLASH_BUFFER_START_ADDRESS 0x0800EC00//59

//片区长度 2字节
#define BLOCK_SIZE 0x0400
#define BLOCK_UID_SIZE 250
#define UID_FLASH_SIZE 0x1000

//下一片区的加上片区长度偏移量*(X-1)
#define UID_4BYTE_FIRST 0x0800F000 //第一个片区uid个数 2字节 最大值为250*2
#define UID_4BYTE_ADDCARD_UID (UID_4BYTE_FIRST+2) //增加卡片的管理员卡uid
#define UID_4BYTE_SUBCARD_UID (UID_4BYTE_FIRST+6)	//减小卡片的管理员卡uid
#define ADMIN_KEY (UID_4BYTE_FIRST+10) //管理员密码
#define USER_KEY  (UID_4BYTE_FIRST+16) //用户密码
#define UID_4DATA_ADDRESS (UID_4BYTE_FIRST+22) //UID数据开始地址


typedef enum
{
	KEY_OK,
	KEY_ERR,
	CARD_ERR,
	CARD_OK,
	FORMAT_ERR,
	FORMAT_OK,
	WRITE_OK,
	WRITE_ERR,
	ERASE_ERR,
	ERASE_OK,
	FLASH_OK,
}key_enum;

typedef union
{
	uint8_t uid_byte[4];
	uint32_t uid_buf;
}uid_4byte;

typedef union
{
	uint8_t keys[6];
	uint16_t key_buf[3];
}key_6byte;




//连续写4字节数组，此函数不包含擦除！
key_enum Flash_ConWrite(uint32_t address,uint32_t *data,uint16_t size);
//将一片区数据存入另一片区
key_enum Flash_BufferWrite(uint32_t address,uint16_t size,
uint32_t data_address);


//增加减少uid
key_enum Flash_UID_Write(uint8_t com,uint8_t cln,uint32_t address,
uint32_t *data,uint16_t size,uint32_t block_address);


//修改密码
void Flash_Changekey(uint8_t com,key_6byte *buf);

key_enum Format_moudle(void);//格式化数据
//清空缓冲区
key_enum Format_Buf(void);

void read_4bytebuf(uint32_t address,uint32_t *buf,uint16_t length);
void read_2bytebuf(uint32_t address,uint16_t *buf,uint16_t length);
void flash_init(void);

uint8_t IsaddOrsub(uint8_t cln,uint8_t *uid);

uint8_t Compare_4UID(uint8_t *uid,uint16_t *index,uint8_t *block_num);


void Change_AdminUid(uint8_t cln,uint8_t *uid,uint8_t com);

void format_card(void);

void getkey(key_6byte *admin_key,key_6byte *user_key);
#endif
